package com.yzi.core.collection
{
	import flash.utils.Dictionary;

	public class Set implements ICollection
	{
		private var m_set:Dictionary;
		private var m_size:int;
		
		public function Set()
		{
			init();
		}
		
		private function init(): void
		{
			m_set = new Dictionary(true);
			m_size = 0;
		}
		
		public function Clear():void { init(); }
		
		public function Size():int { return m_size;	}
		
		public function get($object:*): *
		{
			var result:* = m_set[$object];
			return (result != undefined ? result : null);
		}
		
		public function set($object:*): void
		{
			if($object == null || $object == undefined || m_set[$object]) return;
			
			m_set[$object] = $object;
			m_size++;
		}
		
		public function Remove($object:*): Boolean
		{
			var result:Boolean = false;
			if(m_set[$object] != undefined) {
				delete m_set[$object];
				m_size--;
			}
			
			return result;
		}
		
		public function Dump(): String
		{
			var result:String = "Set:\n";
			for each(var object:* in m_set) result += "[value : " + object + "]\n";
			
			return result;
		}
		
		public function IsContain($object:*):Boolean { return (m_set[$object] != undefined); }
		
		public function IsEmpty():Boolean {	return (m_size == 0); }
		
		public function ToArray():Array
		{
			var result:Array = new Array(m_size);
			var j:int = 0;
			
			for each(var object:* in m_set) result[j++] = object;			
			
			return result;
		}
		
		public function ToString(): String { return "[Set, size = " + m_size + "]"; }
	}
}
import com.yzi.core.collection.IIterator;
import com.yzi.core.collection.Set;

internal class SetIterator implements IIterator
{
	private var m_set:Set;
	private var m_list:Array;
	private var m_cursor:int;
	private var m_size:int;
	
	public function SetIterator($set:Set)
	{
		m_set = $set;
		init();
	}
	
	private function init(): void
	{
		m_list = m_set.ToArray();
		m_cursor = 0;
		m_size = m_set.Size();
	}
	
	public function Start(): void { m_cursor = 0; }
	
	public function Next(): * { return m_list[m_cursor++]; }
	
	public function HasNext(): Boolean { return (m_cursor < m_size); }
	
	public function get data(): * { return m_list[m_cursor]; }
	
	public function set data($object:*): void
	{
		m_set.Remove(m_list[m_cursor]);
		m_set.set($object);
	}
}